package gov.fema.hazus.bdc.client;

import gov.fema.hazus.bdc.client.controller.Controller;
import gov.fema.hazus.bdc.client.login.Login;
import gov.fema.hazus.bdc.client.map.Map;
import gov.fema.hazus.bdc.client.search.Search;
import gov.fema.hazus.bdc.client.settings.Settings;
import gov.fema.hazus.bdc.client.ui.BuildingEditor;
import gov.fema.hazus.bdc.client.ui.BuildingList;
import gov.fema.hazus.bdc.client.ui.LeftNavigation;
import gov.fema.hazus.bdc.client.ui.RightNavigation;
import gov.fema.hazus.bdc.client.ui.TopNavigation;

import com.google.gwt.core.client.GWT;
import com.google.gwt.event.logical.shared.ResizeEvent;
import com.google.gwt.event.logical.shared.ResizeHandler;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.WindowResizeListener;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.DockPanel;
import com.google.gwt.user.client.ui.HasHorizontalAlignment;
import com.google.gwt.user.client.ui.VerticalPanel;

/*
 * The container for the entire UI
 */
public class MainUI extends Composite implements ResizeHandler {

    private static MainUI singleton;
    public static MainUI get()
    {
        if( singleton == null )
        {
            singleton = new MainUI();
        }
        return singleton;
    }
    
	/*
	 * Docker holds vpanels, which contain custom widgets
	 */
	private DockPanel docker = new DockPanel();
	
	/*
	 * Vertical panels which will occupy each direction
	 * position of the docker and hold their own custom widgets
	 */
    private VerticalPanel north = new VerticalPanel();
    private VerticalPanel south = new VerticalPanel();
    private VerticalPanel east = new VerticalPanel();
    private VerticalPanel west = new VerticalPanel();
    private VerticalPanel center = new VerticalPanel();
    
    /*
     * Custom widgets
     */
    private Map map = Map.get();
    private TopNavigation topNavigation = TopNavigation.get();
    private LeftNavigation leftNavigation = LeftNavigation.get();
    private RightNavigation rightNavigation = RightNavigation.get();
    private Settings settings = Settings.get();
    private BuildingList buildingList = BuildingList.get();
    private BuildingEditor buildingEditor = BuildingEditor.get();
	private Search search = Search.get();

	private Constants constants;
    
    public MainUI()
    {
    	
    	singleton = this;
    	
        Window.addResizeHandler(this);
    	
    	// constants
		constants = (Constants)GWT.create(Constants.class);
		
    	// assign nav elements to corresponding vpanels
    	north.add(topNavigation);
    	north.setWidth("100%");
    	north.setCellWidth(topNavigation, "100%");
    	north.setCellHorizontalAlignment(topNavigation, HasHorizontalAlignment.ALIGN_RIGHT);
    	
    	north.add(search);
    	east.add(rightNavigation);
    	
    	// a number of widgets go in the center vertical panel
    	center.setStyleName("main-ui-center-vertical-panel");
    	
    	center.add(settings);
    	center.setCellHeight(settings, "100%");
    	
    	center.add(buildingList);
    	center.setCellHeight(buildingList, "100%");
    	
    	center.add(buildingEditor);
    	center.setCellHeight(buildingEditor, "100%");
    	
    	center.add(map);
    	center.setCellWidth(map, "100%");
    	center.setCellHeight(map, "400px"); // map heights need to be pixels, not percentage
    	
    	west.setStyleName("main-ui-west-vertical-panel");
    	west.add(leftNavigation);
    	// constrain left nav
    	west.setCellWidth(leftNavigation, "150px");
    	
    	// load docker
    	docker.add(north, DockPanel.NORTH);
    	docker.add(east, DockPanel.EAST);
    	docker.add(west, DockPanel.WEST);
    	docker.add(center, DockPanel.CENTER);
    	
    	// constrain the left nav ** this did it **
    	docker.setCellWidth(west, "150px");
    	
    	docker.setStyleName("main-ui-docker");
    	
    	initWidget(docker);
    	
    }
	
    private native void reloadApplication()/*-{
	    var currLocation = $wnd.location.toString();
	    var noHistoryCurrLocArray = currLocation.split("#");
	    var noHistoryCurrLoc = noHistoryCurrLocArray[0];
	    var locArray = noHistoryCurrLoc.split("?");
	    $wnd.location.href = locArray[0];
	}-*/;
    
	public static void actionWrapperLogin()
	{
		Controller.get().hideUI();
		GWT.log("Login null? " + Login.get(), null);
		GWT.log("Login is attached? " + Login.get().isAttached(), null);
		if( Login.get() != null && Login.get().isAttached() )
		{
			GWT.log("Login set visible false", null);
			Login.get().setVisible(false);
		}
		GWT.log("TopNav update user name", null);
		TopNavigation.get().updateUserName();
		GWT.log("Controller building list get buildings", null);
		Controller.get().buildingListGetBuildings();
	}
	
    public static void actionWrapperLogout()
    {
    	MainUI.get().reloadApplication();
    }
    
    public static void actionWrapperShowBuildingEditor()
    {
    	GWT.log("MainUI.actionWrapperShowBuildingEditor", null);
    	BuildingList.get().setVisible(false);
    	Settings.get().setVisible(false);
    	BuildingEditor.get().setVisible(true);
    	Controller.get().mapSetVisible(false);
    }

    public static void actionWrapperShowUserEditor()
    {
    	GWT.log("MainUI.actionWrapperShowUserEditor", null);
    	BuildingList.get().setVisible(false);
    	BuildingEditor.get().setVisible(false);
    	Controller.get().mapSetVisible(false);
    	Settings.get().showUserEditor();
    }
    
    public static void actionWrapperShowUserList()
    {
    	GWT.log("MainUI.actionWrapperShowUserList", null);
    	BuildingList.get().setVisible(false);
    	BuildingEditor.get().setVisible(false);
    	Controller.get().mapSetVisible(false);
    	Settings.get().showUserList();
    }
    
    public static void actionWrapperShowBuildingList()
    {
    	
    	GWT.log("actionWrapperShowBuildingList", null);
    	
    	BuildingEditor.get().setVisible(false);
    	
    	Login.get().setVisible(false);
    	MainUI.get().setVisible(true);
    	
    	Window.enableScrolling(true);
    	BuildingList.get().setVisible(true);
    	Settings.get().setVisible(false);
    	
    	MainUI.get().onWindowResized(Window.getClientWidth(), Window.getClientHeight());
    	
    	Controller.get().mapSetVisible(false);
    }
    
    public static void actionWrapperShowBuildingMap()
    {
    	GWT.log("actionWrapperShowBuildingMap...", null);
    	Settings.get().setVisible(false);
    	BuildingList.get().setVisible(false);
    	BuildingEditor.get().setVisible(false);
    	LeftNavigation.get().highlightMapLeftNav();
    	
    	/* replace with controller delegators
    	Map.get().setVisible(true);
    	Map.get().resize(Window.getClientWidth(), Window.getClientHeight());
    	Map.get().getBuildings();
    	*/
    	GWT.log("Firing map action wrappers from Controller", null);    	
    	Controller.get().mapSetVisible(true);
    	Controller.get().mapResize(Window.getClientWidth(), Window.getClientHeight());
    	Controller.get().mapGetBuildings();
    }    
    
    public static void actionWrapperShowLoginPage()
    {
    	MainUI.get().setVisible(false);
    	Login.get().setVisible(true);
    }    
    
    public static void actionWrapperShowSettings()
    {
    	Map.get().setVisible(false);
    	BuildingEditor.get().setVisible(false);
    	BuildingList.get().setVisible(false);
    	Settings.get().showSettings();
    } 
    
    public void showMainUI()
    {
    	GWT.log("Show MainUI", null);
    }

	public void showBuildingList() {

        Window.enableScrolling(true);
        
        Map.get().setVisible(false);
        BuildingEditor.get().setVisible(false);
        Settings.get().setVisible(false);
        BuildingList.get().setVisible(true);
        
        MainUI.get().onWindowResized(Window.getClientWidth(), Window.getClientHeight());
        
	}

	public void setSearchBorder(boolean b) {
		/*
        if( flag )
        {
            vpanel.setStyleName("body-main-search");  
        }
        else
        {
            vpanel.setStyleName("body-main");
        }
		 */
	}

	public void onWindowResized(int width, int height) {
		
		GWT.log("MainUI onWindowResized=" + width, null);
		try
		{
			
			// GWT.log("map visible on window resize event trigger=" + map.isVisible(), null);
			
	        // get width of window
	        int windowWidth = width;
	
	        // get width of left
	        int leftWidth = leftNavigation .getOffsetWidth();
	        int rightWidth = rightNavigation.getOffsetWidth();
	        
	        int newMapWidth = windowWidth - (leftWidth + rightWidth);
	        newMapWidth = newMapWidth - 10; // border added via css (only right side) - see .map in incast.css
	        //newMapWidth = newMapWidth - rightWidth;
	        String mapWidth = Integer.toString(newMapWidth);
	        
	        GWT.log("window width=" + windowWidth, null);
	        GWT.log("left width=" + leftWidth, null);
	        GWT.log("right width=" + rightWidth, null);
	        GWT.log("new map width=" + newMapWidth, null);
	        GWT.log("set map width to=" + newMapWidth, null);
	        
	        //TODO: hook up map: map.setWidth(mapWidth);
	        
	        // vpanel.setCellWidth(map, mapWidth);
	        
	        
	        // start height
	        GWT.log("window height=" + height, null);
	        // css sets top to 20, search to 80 and footer to 40 (.south), another 20 for map border, so subtract 160
	        int newMapHeight = height - 160;
	        newMapHeight = newMapHeight - 20; // border added via css - see .map in incast.css
	        String mapHeight = Integer.toString(newMapHeight);
	        GWT.log("window height=" + newMapHeight, null);

	        GWT.log("SFM widget height=" + mapHeight, null);
	        mapWidth = mapWidth + "px";
	        mapHeight = mapHeight + "px";
	        
	        // set map composite width/height
	        map.setWidth(mapWidth);
	        map.setHeight(mapHeight);
	        // and then the inner map widget's width/height
	        // map.resize(newMapWidth, newMapHeight);
	        
	        buildingList.setWidth(mapWidth);
	        buildingList.setHeight(mapHeight);
	        
	        // do the same for building editor
	        buildingEditor.setWidth(mapWidth);
	        buildingEditor.setHeight(mapHeight);
	        
	        // and for the settings panel
	        settings.setWidth(mapWidth);
	        settings.setHeight(mapHeight);
	        
	        // and the building list
	        buildingList.setWidth(mapWidth);
	        buildingList.setHeight(mapHeight);
		}
		catch (Exception e) {
			GWT.log("Trouble resizing=" + e.getMessage(), null);
		}
	}
	
	// propertyGetMainUINorthHeight
	public static int propertyGetMainUINorthHeight()
	{
		GWT.log("MAINUI: propertyGetMainUINorthHeight=" + MainUI.get().getMainUINorthHeight(), null);
		return MainUI.get().getMainUINorthHeight();
	}

	private int getMainUINorthHeight() {
		return this.north.getOffsetHeight();
	}

	public void onResize(ResizeEvent event) {
		onWindowResized(event.getWidth(), event.getHeight());
	}	
}
